package com.kk.datastructure.hashtab;
import java.util.Scanner;

/**
 * title: 
 * @author 阿K
 * 2020年12月27日 下午11:23:07 
 */
public class HashTabDemo {

	public static void main(String[] args) {
		// 创建哈希表
		HashTab hashTab = new HashTab(7);

		// 写一个简单的菜单
		String key = "";
		Scanner scanner = new Scanner(System.in);
		while (true) {
			System.out.println("add:  添加雇员");
			System.out.println("list: 显示雇员");
			System.out.println("find: 查找雇员");
			System.out.println("exit: 退出系统");

			key = scanner.next();
			switch (key) {
			case "add":
				System.out.println("输入id");
				int id = scanner.nextInt();
				System.out.println("输入名字");
				String name = scanner.next();
				// 创建 雇员
				Emp emp = new Emp(id, name);
				hashTab.add(emp);
				break;
			case "list":
				hashTab.list();
				break;
			case "find":
				System.out.println("请输入要查找的id");
				id = scanner.nextInt();
				hashTab.findEmpById(id);
				break;
			case "exit":
				scanner.close();
				System.exit(0);
			default:
				break;
			}
		}
	}

}

// hashTab 哈希表，用户管理链表
class HashTab {
	private EmpLinkedList[] empLinkedListArray;
	private int size;// 链表条数

	// 构造器(一系列初始化工作
	public HashTab(int size) {
		this.size = size;
		// 初始化 hashTab，
		// 注：不仅仅初始化 hashTab ，以及存放的 linkedList也需要初始化
		empLinkedListArray = new EmpLinkedList[size];
		for (int i = 0; i < empLinkedListArray.length; i++) {
			empLinkedListArray[i] = new EmpLinkedList();
		}
	}

	// 添加
	public void add(Emp emp) {
		// 获取店员的id，根据id 决定应当添加到哪条链表
		int empLinkedListNo = hashCodeLow(emp.id);
		// 将 emp 添加到对应的链表中
		empLinkedListArray[empLinkedListNo].add(emp);
	}

	// 遍历 hashtab == 遍历所有链表
	public void list() {
		for (int i = 0; i < size; i++) {
			empLinkedListArray[i].list(i);
		}
	}

	// 根据输入的 id ，查找店员
	public void findEmpById(int id) {
		// 使用散列函数值，确定在哪条链表进行查找
		int empLinkedListNo = hashCodeLow(id);
		Emp emp = empLinkedListArray[empLinkedListNo].findEmpById(id);
		if (emp != null) {// 找到
			System.out.printf("在第%d条链表中找到 店员 id = %d\n", (empLinkedListNo + 1), id);
		} else {
			System.out.println("在哈希表中，没有找到该店员~");
		}
	}

	// 散列函数（低配版--源码可能比较牛逼）
	public int hashCodeLow(int id) {
		return id % size;
	}

}

// 链表
class EmpLinkedList {
	// 头节点，直接指向 第一个 emp
	private Emp head;

	// 添加：
	// 1、若添加店员时，id总是从小到大自增长，因此我们该将店员直接插入到链表最后即可
	public void add(Emp emp) {
		// 若添加的是第一个店员
		if (head == null) {
			head = emp;
			return;
		}
		// 若不是则需要一个辅助直接，帮助定位到最后
		Emp curEmp = head;
		while (true) {
			if (curEmp.next == null) {// 到了最后一个节点
				break;
			}
			curEmp = curEmp.next;// 后移
		}
		// 退出时，直接将 emp 插入到链表中
		curEmp.next = emp;
	}

	// 遍历
	public void list(int no) {
		if (head == null) {
			System.out.println("第" + (no + 1) + "个链表为空");
			return;
		}
		System.out.println("第" + (no + 1) + "个链表的信息如下：");
		// 召唤用于遍历的辅助指针
		Emp curEmp = head;
		while (true) {
			System.out.printf(" => id=%d name=%s\t", curEmp.id, curEmp.name);
			if (curEmp.next == null) {
				// 已经到最后一个节点
				break;
			}
			curEmp = curEmp.next;// 后移
		}
		System.out.println();
	}

	// 要查找的店员 id
	public Emp findEmpById(int no) {
		// 判空
		if (head == null) {
			System.out.println("空链表，您查找的鸡儿？");
			return null;
		}
		// 辅助指针，查找
		Emp temp = head;
		while (true) {
			if (temp.id == no) {
				// 找到
				break;
			}
			// 说明遍历到最后还是没找到(退出
			if (temp.next == null) {
				temp = null;// 既没找到，最终要返回的就是 null
				break;
			}
			temp = temp.next;// 后移
		}
		return temp;
	}
	
	// 删除 根据id
	
}

// 店员
class Emp {
	public int id;
	public String name;
	public Emp next;// 默认 null

	public Emp(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
}
